using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;
using log4net.Core;
using Quiki.ExpressionParsers;

namespace Quiki.Templates
{
    public class SeeAlsoTemplate : NVelocityBasedWikiTemplate
    {
        public SeeAlsoTemplate(
            ITemplatingEngine templatingEngine, 
            ILogger logger, 
            DocumentProcessorSettings documentProcessorSettings)
            : base(templatingEngine, logger, documentProcessorSettings)
        {
        }

        public override string TemplateName
        {
            get { return "See also"; }
        }

        public override void Expand(WikiTemplateElement element, WikiDocument document, DocumentGraph documentGraph)
        {
            List<WikiInternalLinkElement> links = FindLinks (element);
            FindAlternativeNames(element, links);
            element.Properties["links"] = links;

            foreach (WikiInternalLinkElement link in links)
                element.ChildElements.Add(link);
        }

        private static List<WikiInternalLinkElement> FindLinks (WikiTemplateElement element)
        {
            List<WikiInternalLinkElement> links = new List<WikiInternalLinkElement> ();

            foreach (string parameter in element.TemplateParameters)
            {
                Match match = alternativeNameRegex.Match(parameter);
                if (false == match.Success)
                {
                    WikiInternalLinkElement linkElement = new WikiInternalLinkElement ();
                    linkElement.Reference = new WikiDocReference(parameter);
                    links.Add (linkElement);
                }
            }

            return links;
        }

        private void FindAlternativeNames (WikiTemplateElement element, List<WikiInternalLinkElement> links)
        {
            foreach (string parameter in element.TemplateParameters)
            {
                Match match = alternativeNameRegex.Match (parameter);
                if (match.Success)
                {
                    int i = int.Parse(match.Groups["i"].Value, CultureInfo.InvariantCulture);

                    if (i < 1 || i > links.Count)
                        Logger.Log(Level.Warn, "See also alternative link index {0} does not exist", i);
                    else
                        links[i - 1].LinkText = match.Groups["name"].Value;
                }
            }
        }

        private static Regex alternativeNameRegex = new Regex("^l(?<i>[0-9]+)=(?<name>.*)");
    }
}